package com.xbongbong.saas.service.toolbox.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.sys.help.PackageWhitelistHelp;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.SaasTableCountTypeEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.errorcodes.BiErrorCodeEnum;
import com.xbongbong.pro.statistic.enums.ChartTypeEnum;
import com.xbongbong.pro.statistic.enums.StatisticsTypeEnum;
import com.xbongbong.pro.statistic.model.ChartCustomModel;
import com.xbongbong.pro.statistic.pojo.SlaveSourcePojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.toolbox.help.BasicHelper;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 套餐
 * 创建时间 2019/5/13 11:04 AM
 * 修改时间 2019/5/13 11:04 AM
 * @author chy
 * @since v1.0
 * @version v1.0
 */
@Service("updatePackageRedisService")
public class UpdatePackageRedisService {

    private static final Logger LOG = LoggerFactory.getLogger(UpdatePackageRedisService.class);

    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private ChartCustomModel chartCustomModel;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private PackageWhitelistHelp packageWhitelistHelp;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private UpdatePackageRedisHelp updatePackageRedisHelp;


    /**
     * 从缓存获取套餐信息
     * @param corpid
     * @param valueAddedTypeEnum
     * @param xbbRefTypeEnum 指定saas业务的单表数据量时，需要传 参照 {@link com.xbongbong.pro.enums.SaasTableCountTypeEnum}
     * @param formId 自定义表单的单表数据量时，需要传
     * @return
     * 创建时间 2019/7/4 5:33 PM
     * 修改时间 2019/7/4 5:33 PM
     * @author chy
     * @since v1.0
     * @version v1.0
     */
    public JSONObject getPaasPackageFromRedis(String corpid, ValueAddedTypeEnum valueAddedTypeEnum, XbbRefTypeEnum xbbRefTypeEnum, Long formId) {

        Integer type = valueAddedTypeEnum.getType();
        String key = corpid + "_" + type;
        String value = null;

        if (Objects.equals(valueAddedTypeEnum, ValueAddedTypeEnum.ONE_FORM_DATA_NUM)) {
            xbbRefTypeEnum = Objects.isNull(xbbRefTypeEnum) ? XbbRefTypeEnum.PAAS : xbbRefTypeEnum;

            if (SaasTableCountTypeEnum.isSaasData(xbbRefTypeEnum)) {
                key += "_" + xbbRefTypeEnum.getCode();
            } else if (Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.SYSTEM)
                    || Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.PAAS)) {
                key += "_" + xbbRefTypeEnum.getCode() + "_" + formId;
            }
            value = paasRedisHelper.getValue(RedisPrefixConstant.VALUE_ADDED,
                    key);
        } else {
            value = paasRedisHelper.getValue(RedisPrefixConstant.VALUE_ADDED,
                    key);
        }

        if (StringUtil.isEmpty(value)) {
            return null;
        }

        JSONObject packageFromRedis = null;

        try {
            packageFromRedis = JSONArray.parseObject(value);
        } catch (Exception e) {
            //异常时返回null
        }

        return packageFromRedis;
    }

    public Map<String, Long> getCountMap(Map<String, Long> countMap, String corpid, Long formId, XbbRefTypeEnum xbbRefTypeEnum) throws XbbException {
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("formId", formId);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        //解析查询条件
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", 0));
        boolQueryBuilder.filter(termQuery("formId", formId));
        boolQueryBuilder.filter(termsQuery("flowStatus",new ArrayList<Integer>(){{add(FlowStatusEnum.NOT_NEED_APPROVAL.getType());add(FlowStatusEnum.PASS.getType());}}));
        long count = 0;
        switch (xbbRefTypeEnum) {
            case ASSEMBLE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_ASSEMBLE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_ASSEMBLE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case BOM_BILL:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_BOM.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_BOM.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case COMMUNICATE_PLAN:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_COMMUNICATE_PLAN.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CONTRACT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CUSTOMER_MANAGEMENT:
                IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(customerIndex.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case INSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_INSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_INSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case INVENTORY:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_INVENTORY.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_INVENTORY.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case SALES_OPPORTUNITY:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OPPORTUNITY.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OPPORTUNITY.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PAY_PLAN:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PAY_PLAN.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAY_PLAN.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PAY_SHEET:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYPLAN_SHEET.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PAYMENT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PAYMENT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYMENT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PAYMENT_SHEET:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PRODUCT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PRODUCT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PRODUCT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PRODUCTION_ORDER:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PRODUCTION_ORDER.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PURCHASE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PURCHASE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PURCHASE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case REFUND:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_REFUND.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_REFUND.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case RETURNED_PURCHASE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case SUPPLIER:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_SUPPLIER.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_SUPPLIER.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case SUPPLIER_COMMUNICATE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_SUPPLIER_COMMUNICATE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_SUPPLIER_COMMUNICATE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case SUPPLIER_CONTACT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_SUPPLIER_CONTACT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_SUPPLIER_CONTACT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case TRANSFER:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_TRANSFER.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_TRANSFER.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case WORK_ORDER:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_WORK_ORDER.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_WORK_ORDER.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case WORK_REPORT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_WORK_REPORT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_WORK_REPORT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CONTRACT_PRODUCT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT_PRODUCT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CONTACT:
                sourceBuilder = new SearchSourceBuilder();
                boolQueryBuilder = boolQuery();
                //解析查询条件
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termQuery("del", 0));
                boolQueryBuilder.filter(termQuery("formId", formId));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTACT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTACT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CUSTOMER_COMMUNICATE:
                sourceBuilder = new SearchSourceBuilder();
                boolQueryBuilder = boolQuery();
                //解析查询条件
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termQuery("del", 0));
                boolQueryBuilder.filter(termQuery("logType",0));
                boolQueryBuilder.filter(termQuery("formId", formId));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PREPAY_BALANCE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_PAY_BALANCE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_PAY_BALANCE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PURCHASE_INSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PURCHASE_INSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PURCHASE_INSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case REFUND_INSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_REFUND_INSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_REFUND_INSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case OTHER_INSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OTHER_INSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OTHER_INSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PRODUCTION_INSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PRODUCTION_INSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PRODUCTION_INSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case RETURNED_MATERIEL_INSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_RETURNED_MATERIEL_INSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_RETURNED_MATERIEL_INSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CONTRACT_OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case RETURNED_PURCHASE_OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_RETURNED_PURCHASE_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case OTHER_OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OTHER_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OTHER_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_PRODUCTION_MATERIEL_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_PRODUCTION_MATERIEL_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case WORK_ORDER_OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_WORK_ORDER_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_WORK_ORDER_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case WAREHOUSE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_WAREHOUSE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_WAREHOUSE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
//            case STOCK_SEARCH:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_STOCK_SEARCH.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case WARNING_SEARCH:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case GUARANTEE_SEARCH:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case STOCK_FLOW_BILL:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case STOCK_STANDING_BOOK:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case SEQ_SEARCH:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case BATCH_FLOW_BILL:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case SIGNIN:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case SIMULATED_PRODUCTION:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
            case QUOTATION:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_QUOTATION.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_QUOTATION.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case REIMBURSEMENT_FORM:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_REIMBURSEMENT_FORM.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_REIMBURSEMENT_FORM.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case EXPENSE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_EXPENSE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_EXPENSE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
//            case PAYMENT_TASK:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case CREDIT_LIMIT:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case CREDIT_TEMPORARY_LIMIT:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case CREDIT_FIXED_LIMIT:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case CUSTOMER_STATEMENT:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case CUSTOMER_STATEMENT_STATISTIC:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
            case ONLINE_PAYMENT_FLOW:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_ONLINE_PAYMENT_FLOW.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_ONLINE_PAYMENT_FLOW.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case OTHER_INCOME:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OTHER_INCOME.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OTHER_INCOME.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case OTHER_EXPENSE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OTHER_EXPENSE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OTHER_EXPENSE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case FUND_TRANSFER:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_FUND_TRANSFER.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_FUND_TRANSFER.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
//            case MARKETING_ACTIVITY:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case MARKETING_ACTIVITY_MANAGEMENT:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case PROMOTION_ACTIVITY:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
//            case PROMOTION_ACTIVITY_MANAGEMENT:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
            case DISTRIBUTOR_ACCOUNT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_DISTRIBUTOR_ACCOUNT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_DISTRIBUTOR_ACCOUNT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case DISTRIBUTOR_MANAGEMENT:
                customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, customerIndex.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(customerIndex.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case DISTRIBUTOR_CONTACT:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case DISTRIBUTOR_COMMUNICATE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case ORDER:
                boolQueryBuilder.filter(termQuery("data." + ContractEnum.IS_RED.getAttr(), 0));
                boolQueryBuilder.filter(termQuery( "data." + ContractEnum.ARCHIVED.getAttr(), 2));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case RETURN:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_REFUND.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_REFUND.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case ORDER_OUTSTOCK:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_OUTSTOCK.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_OUTSTOCK.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
//            case DISTRIBUTOR_ORDER:
//                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CONTRACT.getType()));
//                sourceBuilder.query(boolQueryBuilder);
//                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CONTRACT.getIndex());
//                searchRequest.source(sourceBuilder);
//                count = paasFormDataEsModel.count(searchRequest);
//                break;
            case CLUE:
                boolQueryBuilder.filter(termQuery("data." + ClueEnum.IS_PUBLIC.getAttr(), 0));
                boolQueryBuilder.filter(termQuery( "data." + ClueEnum.IS_ARCHIVED.getAttr(), 2));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CLUE_PUBLIC:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case CLUE_RECYCLE:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case MARKET_ACTIVITY:
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_MARKET_ACTIVITY.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_MARKET_ACTIVITY.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            case PAAS:
                sourceBuilder = new SearchSourceBuilder();
                boolQueryBuilder = boolQuery();
                //解析查询条件
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termQuery("del", 0));
                boolQueryBuilder.filter(termQuery("formId", formId));
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_FORM_DATA.getType()));
                sourceBuilder.query(boolQueryBuilder);
                searchRequest = new SearchRequest(IndexTypeEnum.IDX_FORM_DATA.getIndex());
                searchRequest.source(sourceBuilder);
                count = paasFormDataEsModel.count(searchRequest);
                break;
            default:
                break;
        }
        countMap.put(formId.toString(), count);
        return countMap;
    }

    /**
     * 校验表单数据量是否超过限制
     *
     * @param selectList 表单实体数组
     * @param corpid 公司唯一标识
     * @param biDataLimit 限制量
     * @author zyy
     * @date 2022/11/2
     * @version v1.0
     */
    public void chartLimit(List<SlaveSourcePojo> selectList, String corpid, long biDataLimit ) throws XbbException {
        //获取公司下表单已用数据量的缓存
        String jsonStr = getChartDataLimitCache(corpid);
        if(StringUtil.isEmpty(jsonStr)){
            //从来没用过该公司的表单,则从es库中查询表单使用的数据量
            Map<String, Long> countMap = new HashMap<>();
            getCountMap(corpid, selectList, countMap);
            //更新公司下表单已用数据量的缓存
            refreshChartDataLimitCache(corpid,countMap);
            //校验是否图表已用数据量是否超过限制
            checkDataCount(corpid,selectList,countMap,biDataLimit);
        }else {
            //用过该公司下的表单，但是不排除部分表单没选过
            JSONObject allSource = JSON.parseObject(jsonStr);
            //校验已使用表单的数据量，并组装没有使用过的表单
            List<SlaveSourcePojo> noUseList = getNoUseList(corpid,selectList,allSource,biDataLimit);
            //校验没有使用过的表单数据量
            if(CollectionsUtil.isNotEmpty(noUseList)){
                Map<String, Long> countMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                getCountMap(corpid, noUseList, countMap);
                //把原来未用表单的数据量追加到缓存里
                allSource.putAll(countMap);
                //更新公司下表单已用数据量的缓存
                refreshChartDataLimitCache(corpid,countMap);
                checkDataCount(corpid,noUseList,countMap,biDataLimit);
            }
        }
    }

    /**
     * 校验已用表单的数据量并获取第一次使用的表单
     *
     * @param corpid 公司唯一标识
     * @param selectList 表单实体数组
     * @param allSource 表单 -> 表单数据量
     * @param biDataLimit 限制量
     * @return java.util.List<com.xbongbong.pro.statistic.pojo.SlaveSourcePojo>
     * @author zyy
     * @date 2022/11/2
     * @version v1.0
     */
    public List<SlaveSourcePojo> getNoUseList(String corpid, List<SlaveSourcePojo> selectList, JSONObject allSource, long biDataLimit) throws XbbException {
        List<SlaveSourcePojo> noUseList = new ArrayList<>();
        for (SlaveSourcePojo slaveSourcePojo : selectList) {
            Long formId = slaveSourcePojo.getFormId();
            //防止前端传值不规范
            if(formId == null){
                continue;
            }
            Long count = allSource.getLong(formId.toString());
            if(count == null){
                noUseList.add(slaveSourcePojo);
                continue;
            }
            if(count > biDataLimit){
                LOG.error(BiErrorCodeEnum.API_ERROR_241015.getCode()+"_"+ formId+"_"+corpid);
                throw new XbbException(BiErrorCodeEnum.API_ERROR_241015,slaveSourcePojo.getName()+I18nMessageUtil.getMessage(BiErrorCodeEnum.API_ERROR_241015.getMsg()));
            }
        }
        return noUseList;
    }

    /**
     * 更新公司下的表单使用的数据量
     *
     * @param corpid 公司唯一标识
     * @param countSource 表单的数据量容器
     * @author zyy
     * @date 2022/11/2
     * @version v1.0
     */
    public void refreshChartDataLimitCache(String corpid, Map<String, Long> countSource) {
        paasRedisHelper.setValue(RedisPrefixConstant.DATA_COUNT_FORM_ID, corpid,countSource, RedisTimeConstant.HUGE_DURATION);
    }

    /**
     * 获取公司下的表单使用的数据量
     *
     * @param corpid 公司唯一标识
     * @return java.lang.String
     * @author zyy
     * @date 2022/11/2
     * @version v1.0
     */
    public String getChartDataLimitCache(String corpid) {
        return paasRedisHelper.getValue(RedisPrefixConstant.DATA_COUNT_FORM_ID, corpid);
    }

    /**
     * 校验数据量
     *
     * @param corpid 公司唯一标识
     * @param selectList 表单实体数组
     * @param countMap 表单的数据量容器
     * @param biDataLimit 限制数据量
     * @author zyy
     * @date 2022/11/2
     * @version v1.0
     */
    public void checkDataCount(String corpid, List<SlaveSourcePojo> selectList,Map<String, Long> countMap,long biDataLimit ) throws XbbException {
        for (SlaveSourcePojo slaveSourcePojo : selectList) {
            Long count =  countMap.get(slaveSourcePojo.getFormId().toString());
            if(count > biDataLimit){
                LOG.error(BiErrorCodeEnum.API_ERROR_241015.getCode()+"_"+slaveSourcePojo.getFormId()+"_"+corpid);
                throw  new XbbException(BiErrorCodeEnum.API_ERROR_241015,slaveSourcePojo.getName()+ I18nMessageUtil.getMessage(BiErrorCodeEnum.API_ERROR_241015.getMsg()));
            }
        }
    }

    private void getCountMap(String corpid, List<SlaveSourcePojo> selectList, Map<String, Long> countMap) throws XbbException {
        for (SlaveSourcePojo slaveSourcePojo : selectList) {
            XbbRefTypeEnum xbbRefTypeEnum = null;
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), slaveSourcePojo.getSaasMark())) {
                xbbRefTypeEnum = XbbRefTypeEnum.getByCode(XbbRefTypeEnum.transferBusinessType4Distributor(slaveSourcePojo.getBusinessType(),slaveSourcePojo.getDistributorMark()));
            } else {
                xbbRefTypeEnum = XbbRefTypeEnum.PAAS;
            }
            getCountMap(countMap, corpid, slaveSourcePojo.getFormId(), xbbRefTypeEnum);
        }
    }



    /**
     * 获取指定增值业务使用及限制值
     * @param corpid
     * @param valueAddedTypeEnum
     * @param xbbRefTypeEnum 指定saas业务的单表数据量时，需要传 参照 {@link com.xbongbong.pro.enums.SaasTableCountTypeEnum}
     * @param formId 自定义表单的单表数据量时，需要传
     * @return {"totalValue":2, "usedValue":1, "status":1}
     * @throws XbbException
     * 创建时间 2019/4/17 10:34 AM
     * 修改时间 2019/4/17 10:34 AM
     * @author chy
     * @since v1.0
     * @version v1.0
     */
    public JSONObject getValueAddInfo(String corpid, ValueAddedTypeEnum valueAddedTypeEnum, XbbRefTypeEnum xbbRefTypeEnum, Long formId) throws XbbException {
        JSONObject valueAddedJson4Redis = getPaasPackageFromRedis(corpid, valueAddedTypeEnum, xbbRefTypeEnum, formId);
        if (valueAddedJson4Redis == null) {
            valueAddedJson4Redis = updatePackageRedisHelp.updatePaasPackage2Redis(corpid, valueAddedTypeEnum, xbbRefTypeEnum, formId);
        }

        //总表单数据量和单表数据量效率表低
        if (valueAddedTypeEnum == ValueAddedTypeEnum.TOTAL_FORM_DATA_NUM
                || valueAddedTypeEnum == ValueAddedTypeEnum.ONE_FORM_DATA_NUM) {
            Long effectiveTime = Long.valueOf(valueAddedJson4Redis.get("effectiveTime").toString());
            if (DateUtil.getInt() > effectiveTime) {
                updatePackageRedisHelp.updateSpecialPaasPackage2Redis(corpid, valueAddedTypeEnum, xbbRefTypeEnum, formId);
            }
        }
        return valueAddedJson4Redis;
    }

    /**
     * 获取已超过总量的数量
     * @param corpid
     * @param valueAddedTypeEnum
     * @return
     * @throws XbbException
     */
    public Integer getOverNum(String corpid, ValueAddedTypeEnum valueAddedTypeEnum) throws XbbException{
        Integer num = 0;
        JSONObject jsonObject = getValueAddInfo(corpid, valueAddedTypeEnum, null, null);
        if (Objects.nonNull(jsonObject)) {
            Integer totalValue = jsonObject.getInteger("totalValue");
            Integer usedValue = jsonObject.getInteger("usedValue");
            if (Objects.nonNull(totalValue) && Objects.nonNull(usedValue)) {
                num = usedValue - totalValue;
            }
        }
        return num;
    }

    /**
     * 套餐限制，获取未使用的数量不包括白名单公司
     * @param corpid
     * @param valueAddedTypeEnum
     * @return
     * @throws XbbException
     */
    public Integer getUnusedNumPackageLimit(String corpid, ValueAddedTypeEnum valueAddedTypeEnum) throws XbbException{
        Integer num = 0;
        Set<String> corpidSet = packageWhitelistHelp.getPackageWhitelist(corpid);
        if (corpidSet.contains(corpid)) {
            return num;
        }
        return getOverNum(corpid, valueAddedTypeEnum);
    }

    /**
     * 业务规则超限
     * 主要是为了处理每个套餐具有的功能
     * @param corpid
     * @return true: 超限 false: 没超限制
     *
     */
    public Boolean businessRuleExceeded(String corpid, Integer feeType) throws XbbException {

        Integer count = getUnusedNumPackageLimit(corpid, ValueAddedTypeEnum.BUSINESS_RULES);
        if (count > 0) {
            return true;
        }
        return false;
    }

    public Integer getTotalPackageLimit(String corpid, ValueAddedTypeEnum valueAddedTypeEnum) throws XbbException{
        Integer num = 0;
        Set<String> corpidSet = packageWhitelistHelp.getPackageWhitelist(corpid);
        if (corpidSet.contains(corpid)) {
            return num;
        }
        JSONObject jsonObject = getValueAddInfo(corpid, valueAddedTypeEnum, null, null);
        if (Objects.nonNull(jsonObject)) {
            num = jsonObject.getInteger("totalValue") == null ? 0 : jsonObject.getInteger("totalValue");
        }
        return num;
    }

    /**
     * 获取套餐内数量的自定义图表
     * @param corpid
     * @return
     * @throws XbbException
     */
    public List<Long> getPackageTotalChartId(String corpid) throws XbbException {
        List<Long> chartIdList = new ArrayList<>();
        Integer useNum = getTotalPackageLimit(corpid, ValueAddedTypeEnum.CUSTOM_CHART_NUM);
        if (useNum > 0) {
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("orderByStr", "add_time ASC");
            map.put("start",  0);
            map.put("pageNum",  useNum);
            map.put("corpid", corpid);
            map.put("del", DelEnum.NORMAL.getDel());
            map.put("statisticsType", StatisticsTypeEnum.CUSTOM_STATISTIC.getCode());
            map.put("chartTypeExclude", ChartTypeEnum.VALUE.getCode());
            map.put(StringConstant.COLUMNS, "id");
            List<ChartEntity> list = (List<ChartEntity>) BasicHelper.findEntitysByImitatePage(map, chartCustomModel, BasicConstant.THREE_HUNDRED);
            if (CollectionsUtil.isNotEmpty(list)) {
                list.forEach(item->{
                    // 创建时间前数量的图表才可以显示出来
                    chartIdList.add(item.getId());
                });
            }
        }
        return chartIdList;
    }
}
